package org.kabeja.math;

import org.kabeja.dxf.DXFExtrusion;
import org.kabeja.dxf.helpers.Point;
import org.kabeja.dxf.helpers.Vector;

/**
 * @author shutao
 * @since 2022/4/24 16:35
 */
public class ParametricPlane {
    protected Point base;
    protected Vector directionX;
    protected Vector directionY;
    protected Vector normal;

    public ParametricPlane(Point var1, Vector var2, Vector var3, Vector var4) {
        this.base = var1;
        this.directionX = var2;
        this.directionY = var3;
        this.normal = var4;
    }

    public ParametricPlane(Point var1, Vector var2, Vector var3) {
        this(var1, var2, var3, MathUtils.normalize(MathUtils.crossProduct(var2, var3)));
    }

    public ParametricPlane(Point var1, Point var2, Vector var3) {
        this(var1, MathUtils.normalize(MathUtils.getVector(var1, var2)), MathUtils.normalize(MathUtils.crossProduct(var3, MathUtils.normalize(MathUtils.getVector(var1, var2)))), var3);
    }

    public ParametricPlane(Point var1, Point var2, Point var3) {
        this(var1, MathUtils.normalize(MathUtils.getVector(var1, var2)), MathUtils.normalize(MathUtils.getVector(var1, var3)));
    }

    public ParametricPlane(DXFExtrusion var1) {
        this(new Point(0.0D, 0.0D, 0.0D), var1.getDirectionX(), var1.getDirectionY(), var1.getNormal());
    }

    public Point getPoint(double var1, double var3) {
        Point var5 = new Point();
        var5.setX(this.base.getX() + this.directionX.getX() * var1 + this.directionY.getX() * var3);
        var5.setY(this.base.getY() + this.directionX.getY() * var1 + this.directionY.getY() * var3);
        var5.setZ(this.base.getZ() + this.directionX.getZ() * var1 + this.directionY.getZ() * var3);
        return var5;
    }

    public Point getPoint(Point var1) {
        return this.getPoint(var1.getX(), var1.getY());
    }

    public double[] getParameter(Point var1) {
        double var2 = 0.0D;
        double var4 = this.directionX.getY() * this.directionY.getX() - this.directionX.getX() * this.directionY.getY();
        if (var4 != 0.0D) {
            var4 = (var1.getY() * this.directionY.getX() - this.base.getY() * this.directionY.getX() - this.directionY.getY() * var1.getX() + this.base.getX() * this.directionY.getY()) / var4;
        }

        if (this.directionY.getX() != 0.0D) {
            var2 = (var1.getX() - this.base.getX() - this.directionX.getX() * var4) / this.directionY.getX();
        } else if (this.directionY.getY() != 0.0D) {
            var2 = (var1.getY() - this.base.getY() - this.directionX.getY() * var4) / this.directionY.getY();
        } else if (this.directionY.getY() != 0.0D) {
            var2 = (var1.getZ() - this.base.getZ() - this.directionX.getZ() * var4) / this.directionY.getZ();
        }

        return new double[]{var4, var2};
    }

    public boolean isOnPlane(Point var1) {
        double[] var2 = this.getParameter(var1);
        double var3 = this.base.getZ() + this.directionX.getZ() * var2[0] + this.directionY.getZ() * var2[1];
        if (!(Math.abs(var1.getZ() - var3) < 1.0E-5D)) {
            return false;
        } else {
            var3 = this.base.getY() + this.directionX.getY() * var2[0] + this.directionY.getY() * var2[1];
            if (!(Math.abs(var1.getY() - var3) < 1.0E-5D)) {
                return false;
            } else {
                var3 = this.base.getX() + this.directionX.getX() * var2[0] + this.directionY.getX() * var2[1];
                return Math.abs(var1.getX() - var3) < 1.0E-5D;
            }
        }
    }

    public Point getBasePoint() {
        return this.base;
    }

    public void setBasePoint(Point var1) {
        this.base = var1;
    }

    public Vector getDirectionX() {
        return this.directionX;
    }

    public void setDirectionX(Vector var1) {
        this.directionX = var1;
        this.normal = MathUtils.crossProduct(this.directionX, this.directionY);
        this.normal.normalize();
    }

    public Vector getDirectionY() {
        return this.directionY;
    }

    public void setDirectionY(Vector var1) {
        this.directionY = var1;
        this.normal = MathUtils.crossProduct(this.directionX, this.directionY);
        this.normal.normalize();
    }

    public Vector getNormal() {
        return this.normal;
    }
}
